package com.nebula.sirius.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.nebula.sirius.entity.SysDictEntity;
import com.nebula.sirius.entity.SysDictEntityPK;
import com.nebula.sirius.repository.SysDictRepository;
import com.nebula.sirius.service.SysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by Destiny on 04/02/2018 19:53.
 * Monday.
 */
@Service
@Transactional
public class SysDictServiceImpl implements SysDictService {

    @Autowired
    SysDictRepository sysDictDao;

    @Override
    @Cacheable("dict")
    public List<SysDictEntity> getDict(String dictId) {

        Sort sort = Sort.by("dictSeq").ascending();

        Specification condition = (root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> predicates = new ArrayList<>();
            predicates.add(criteriaBuilder.equal(root.get("dictId"), dictId));
            predicates.add(criteriaBuilder.equal(root.get("dictSts"), "Y"));

            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        return sysDictDao.findAll(condition, sort);
    }

    @Override
    @Cacheable("dicts")
    public Page<SysDictEntity> getDict(int page, int size, String searchStr) {

        Sort sort = Sort.by("dictId").ascending().and(Sort.by("dictSeq").ascending());

        HashMap searchMap = JSONObject.parseObject(searchStr, HashMap.class);
        String dictName =
                searchMap.containsKey("dictName") ? searchMap.get("dictName").toString() : "";

        PageRequest pageRequest = PageRequest.of(page - 1, size, sort);

        Specification condition = (root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(dictName)) {
                predicates.add(criteriaBuilder.like(root.get("dictName"), "%" + dictName + "%"));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        return sysDictDao.findAll(condition, pageRequest);
    }

    @Override
    @CacheEvict(value = { "dict", "dicts" }, allEntries = true)
    public void addDict(SysDictEntity sysDictEntity) {
        SysDictEntityPK sysDictEntityPK = new SysDictEntityPK();
        sysDictEntityPK.setDictId(sysDictEntity.getDictId());
        sysDictEntityPK.setDictKey(sysDictEntity.getDictKey());
        if (sysDictDao.existsById(sysDictEntityPK)) {
            throw new RuntimeException("当前数据字典定义已经存在");
        }
        sysDictDao.save(sysDictEntity);
    }

    @Override
    @CacheEvict(value = { "dict", "dicts" }, allEntries = true)
    public void editDict(SysDictEntity sysDictEntity) {
        SysDictEntityPK sysDictEntityPK = new SysDictEntityPK();
        sysDictEntityPK.setDictId(sysDictEntity.getDictId());
        sysDictEntityPK.setDictKey(sysDictEntity.getDictKey());
        if (!sysDictDao.existsById(sysDictEntityPK)) {
            throw new RuntimeException("当前数据字典定义已经不存在");
        }
        sysDictDao.save(sysDictEntity);
    }

    @Override
    @CacheEvict(value = { "dict", "dicts" }, allEntries = true)
    public void deleteDict(SysDictEntity sysDictEntity) {
        sysDictDao.delete(sysDictEntity);
    }
}
